package com.hang.ad.index.keyword;

import com.hang.ad.index.IndexAware;
import com.hang.ad.utils.CommonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListSet;

@Slf4j
@Component
public class UnitKeywordIndex implements IndexAware<String, Set<Long>> {
    //倒排索引,一个关键词对应多个unitId
    private static Map<String, Set<Long>> keywordMap;
    //正向索引,一个unitId对应多个关键词
    private static Map<Long, Set<String>> unitMap;
    static {
        keywordMap = new ConcurrentHashMap<String, Set<Long>>();
        unitMap = new ConcurrentHashMap<Long, Set<String>>();
    }
    public Set<Long> get(String key) {
        if (StringUtils.isEmpty(key)){
            return Collections.emptySet();
        }
        Set<Long> set = keywordMap.get(key);
        if (set == null){
            return Collections.emptySet();
        }
        return set;
    }

    public void update(String key, Set<Long> value) {
        log.error("不支持update");
    }

    public void add(String key, Set<Long> value) {
        //添加倒排索引
        Set<Long> wordSet = CommonUtils.getOrCreate(key, keywordMap, ConcurrentSkipListSet::new);
        wordSet.addAll(value);
        //添加正向索引
        for (Long id : value){
            Set<String> unitIdSet = CommonUtils.getOrCreate(id, unitMap, ConcurrentSkipListSet::new);
            unitIdSet.add(key);
        }
    }

    public void delete(String key, Set<Long> value) {
        Set<Long> wordSet = CommonUtils.getOrCreate(key, keywordMap, ConcurrentSkipListSet::new);
        wordSet.removeAll(value);

        for (Long id : value){
            Set<String> unitIdSet = CommonUtils.getOrCreate(id, unitMap, ConcurrentSkipListSet::new);
            unitIdSet.remove(key);
        }
    }

    public boolean match(Long unitId, List<String> keywords){
        //unitmap中有unitId,并且该key有值
        if ( unitMap.containsKey(unitId) && CollectionUtils.isNotEmpty(unitMap.get(unitId))){
            Set<String> keywordSet = unitMap.get(unitId);
            return CollectionUtils.isSubCollection(keywords, keywordSet);
        }
        return false;
    }
}
